package com.test.shiro.session.impl;

import java.io.Serializable;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.apache.shiro.session.Session;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import com.test.shiro.session.CustomSessionManager;
import com.test.shiro.session.SessionStatus;
import com.test.shiro.session.ShiroSessionRepository;
import com.test.util.LoggerUtils;
import com.test.util.SerializeUtil;
@SuppressWarnings("all")
@Component("redisShiroSessionRepository")
public class RedisShiroSessionRepository implements ShiroSessionRepository {
//    public static final String REDIS_SHIRO_SESSION = "my-shiro-session:";
//    public static final String REDIS_SHIRO_ALL = "*my-shiro-session:*";
    public static final String REDIS_SHIRO_SESSION = "m:";
    public static final String REDIS_SHIRO_ALL = "*m:*";
    private static final int SESSION_VAL_TIME_SPAN = 18000;
    private static final int DB_INDEX = 1;
    @Resource
	RedisTemplate<String,Object> redisTemplate;
    @Override
    public void saveSession(Session session) {
        if (session == null || session.getId() == null)
            throw new NullPointerException("session is empty");
        try {
            //byte[] key = SerializeUtil.serialize(buildRedisSessionKey(session.getId()));
        	String  key = buildRedisSessionKey(session.getId());
            //不存在才添加。
            if(null == session.getAttribute(CustomSessionManager.SESSION_STATUS)){
            	//Session 踢出自存存储。
            	SessionStatus sessionStatus = new SessionStatus();
            	session.setAttribute(CustomSessionManager.SESSION_STATUS, sessionStatus);
            }
            //byte[] value = SerializeUtil.serialize(session);
            long sessionTimeOut = session.getTimeout() / 1000;
            Long expireTime = sessionTimeOut + SESSION_VAL_TIME_SPAN + (5 * 60);
            //getJedisManager().saveValueByKey(DB_INDEX, key, value, expireTime.intValue());
            redisTemplate.opsForValue().set(key, session, expireTime, TimeUnit.SECONDS);
        } catch (Exception e) {
        	LoggerUtils.fmtError(getClass(), e, "save session error，id:[%s]",session.getId());
        }
    }

    @Override
    public void deleteSession(Serializable id) {
        if (id == null) {
            throw new NullPointerException("session id is empty");
        }
        try {
            //getJedisManager().deleteByKey(DB_INDEX,SerializeUtil.serialize(buildRedisSessionKey(id)));
        	redisTemplate.delete(buildRedisSessionKey(id));
        } catch (Exception e) {
        	LoggerUtils.fmtError(getClass(), e, "删除session出现异常，id:[%s]",id);
        }
    }
   
	@Override
    public Session getSession(Serializable id) {
        if (id == null)
        	 throw new NullPointerException("session id is empty");
        Session session = null;
        try {
            //byte[] value = getJedisManager().getValueByKey(DB_INDEX, SerializeUtil.serialize(buildRedisSessionKey(id)));
        	//session = SerializeUtil.deserialize(value, Session.class);
//        	session = (Session) redisTemplate.opsForValue().get(id);
        	session = (Session) redisTemplate.opsForValue().get(buildRedisSessionKey(id));
            //session = SerializeUtil.deserialize(value.getBytes(), Session.class);
        } catch (Exception e) {
        	LoggerUtils.fmtError(getClass(), e, "获取session异常，id:[%s]",id);
        }
        return session;
    }

    @Override
    public Collection<Session> getAllSessions() {
    	Collection<Session> sessions = new HashSet<Session>();
		try {
			//sessions = getJedisManager().AllSession(DB_INDEX,REDIS_SHIRO_SESSION);
			Set<String> keys = redisTemplate.keys(REDIS_SHIRO_ALL);
			Session session = null;
			for(String key : keys){
				sessions.add(getSession(key.replace(REDIS_SHIRO_SESSION, "")));
			}
		} catch (Exception e) {
			LoggerUtils.fmtError(getClass(), e, "获取全部session异常");
		}
       
        return sessions;
    }

    private String buildRedisSessionKey(Serializable sessionId) {
        return REDIS_SHIRO_SESSION + sessionId;
    }
}
